package com.example.feed;

import android.animation.ValueAnimator;
import android.content.Context;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import com.example.feed.multichannel.ChannelInfo;
import com.example.feed.multichannel.ChannelModel;
import com.example.feed.multichannel.FeedTabPage;
import com.example.uiframework.utils.Utils;
import com.x.uikit.channel.multitabs.DefaultIndicator;
import com.x.uikit.channel.multitabs.ScrollableTabLayout;
import com.x.uikit.page.XPage;

import java.util.ArrayList;
import java.util.List;

public class MultiChannelDemo extends XPage {
    private ViewPager2 mPager;
    private ScrollableTabLayout mTabLayout;
    private ScrollableTabLayout.AbstractAdapter<ChannelInfo, TabItemView> mTabLayoutAdapter;
    private ViewModel mViewModel = new ViewModel();
    private RecyclerView.Adapter<PageViewHolder> mPagerAdapter;
    PagerSnapHelper mPagerSnapHelper;

    public MultiChannelDemo(@NonNull Context context) {
        super(context);
        mTabLayout = new ScrollableTabLayout(getContext());
        mTabLayoutAdapter = new ScrollableTabLayout.AbstractAdapter<ChannelInfo, TabItemView>() {
            @Override
            public int getCount() {
                return mViewModel.getCount();
            }

            @Override
            public TabItemView getView(Context context, int position) {
                ChannelInfo info = mViewModel.getItem(position);
                if (info == null) {
                    return null;
                }
                TabItemView tabItemView = new TabItemView(context, info);
                return tabItemView;
            }
        };
        mTabLayout.addOnTabSelectedListener(new ScrollableTabLayout.OnTabSelectedListenerAdapter() {
            @Override
            public void onTabClicked(int newIndex, int oldIndex) {
                mPager.setCurrentItem(newIndex);
                ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
                animator.setDuration(200);
                animator.setInterpolator(new DecelerateInterpolator());
                animator.removeAllUpdateListeners();
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        float value = (float) animation.getAnimatedValue();
                        mTabLayout.onPageScrolled(oldIndex, newIndex, value);
                    }
                });
                animator.start();
            }
        });
        mTabLayout.setAdapter(mTabLayoutAdapter);
        mTabLayout.setIndicator(new DefaultIndicator());
        int tabLayoutHeight = Utils.res.dpI(48);
        this.addView(mTabLayout, ViewGroup.LayoutParams.MATCH_PARENT, tabLayoutHeight);
        mPager = new ViewPager2(getContext());
        mPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
        mPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            int mLastPosition = 0;
            boolean mNeedScroll = false;

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);
                if (!mNeedScroll) {
                    return;
                }
                int next = position + 1;
                if (next > mTabLayout.getTabCount() - 1) {
                    next = mTabLayout.getTabCount() - 1;
                }
                if (position < mLastPosition) {
                    mTabLayout.onPageScrolled(next, position, 1 - positionOffset);
                } else {
                    mTabLayout.onPageScrolled(position, next, positionOffset);
                }
            }

            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                super.onPageScrollStateChanged(state);
                switch (state) {
                    case ViewPager2.SCROLL_STATE_DRAGGING:
                        mLastPosition = mPager.getCurrentItem();
                        mNeedScroll = true;
                        break;
                    case ViewPager2.SCROLL_STATE_IDLE:
                        mNeedScroll = false;
                        mTabLayout.onPageSelected(mPager.getCurrentItem());
                        break;
                }
            }
        });
        mPagerAdapter = new RecyclerView.Adapter<PageViewHolder>() {
            @NonNull
            @Override
            public PageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                FeedTabPage tabPage = new FeedTabPage(parent.getContext());
                RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                tabPage.setLayoutParams(lp);
                return new PageViewHolder(tabPage);
            }

            @Override
            public void onBindViewHolder(@NonNull PageViewHolder holder, int position) {
                ChannelInfo channelInfo = mViewModel.getItem(position);
                Log.d("jake", "onBindViewHolder position=" + position + "  info=" + channelInfo.toString()+"  hashCode="+holder.hashCode());
                holder.tabPage.bindChannelInfo(channelInfo);
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public int getItemCount() {
                return mViewModel.getCount();
            }
        };
        mPagerAdapter.setHasStableIds(true);
        mPager.setAdapter(mPagerAdapter);
        LayoutParams lpPager = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        lpPager.topMargin = tabLayoutHeight;
        this.addView(mPager, lpPager);
    }

    private static class PageViewHolder extends RecyclerView.ViewHolder {
        FeedTabPage tabPage;

        public PageViewHolder(@NonNull FeedTabPage itemView) {
            super(itemView);
            tabPage = itemView;
        }
    }

    private static class TabItemView extends FrameLayout implements ScrollableTabLayout.IItemView {
        private TextView mTvTitle;
        private static final int COLOR_NORMAL = 0xff999999;
        private static final int COLOR_SELECTED = 0xff0000ff;
        private static final int TEXT_SIZE_NORMAL = Utils.res.dpI(14);
        private static final int TEXT_SIZE_SELECTED = Utils.res.dpI(16);

        public TabItemView(@NonNull Context context, @NonNull ChannelInfo info) {
            super(context);
            mTvTitle = new TextView(getContext());
            mTvTitle.setTextColor(COLOR_NORMAL);
            mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, TEXT_SIZE_NORMAL);
            mTvTitle.setText(info.title);
            mTvTitle.setGravity(Gravity.CENTER);
            this.addView(mTvTitle, Utils.res.dpI(60), -1);
        }

        @Override
        public void selected() {
            mTvTitle.setTextColor(COLOR_SELECTED);
            mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, TEXT_SIZE_SELECTED);
        }

        @Override
        public void unselected() {
            mTvTitle.setTextColor(COLOR_NORMAL);
            mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, TEXT_SIZE_NORMAL);
        }

        @Override
        public View getView() {
            return this;
        }

        @Override
        public void setSlideProgress(float value) {
            mTvTitle.setTextColor(Utils.res.getColor(value, COLOR_NORMAL, COLOR_SELECTED));
            mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, TEXT_SIZE_NORMAL + (TEXT_SIZE_SELECTED - TEXT_SIZE_NORMAL) * value);
        }
    }

    private static class ViewModel {
        private List<ChannelInfo> mChannels = new ArrayList<>();

        public ViewModel() {
            new ChannelModel().readChanel(new ChannelModel.Callback() {
                @Override
                public void onResult(boolean success, List<ChannelInfo> list) {
                    mChannels.addAll(list);
                }
            });
        }

        public int getCount() {
            return mChannels.size();
        }

        public ChannelInfo getItem(int position) {
            return mChannels.get(position);
        }
    }
}
